package com.sti.platform.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.MapUtils;

public class ActUtil {
	
	public static final String START_EVENT = "startEvent";//定义的常量，表示是启动节点
	public static final String SKIP_EXPRESSION ="_ACTIVITI_SKIP_EXPRESSION_ENABLED";//修改任务不自动跳过，要求审批  
	public static final String REJECT_REASON = "reject_reason";//设置驳回原因
	
	/**
	 * 从classpath的资源中加载流程定义Id，一次只能加载一个文件
	 * @return pdId 流程定义ID name 流程定义名
	 */
	public static Map<String,Object> getProcessDefinitionInfo(RepositoryServiceImpl repositoryService){
		if(repositoryService == null){return null;}
		Map<String,Object> result = new HashMap<String,Object>();
        Deployment deployment = repositoryService//与流程定义和部署对象相关的Service
                        .createDeployment()//创建一个部署对象
                        .name("流程定义")//添加部署名称
                        .addClasspathResource("/MyProcess.bpmn")//从classpath的资源中加载，一次只能加载一个文件
                        //.addClasspathResource("/HelloWorld.png")
                        .deploy();//完成部署
        ProcessDefinitionQuery pdQuery = repositoryService.createProcessDefinitionQuery();
		ProcessDefinition  pd = pdQuery.deploymentId(deployment.getId()).singleResult();
        result.put("pdId", pd.getId());
        result.put("name", pd.getName());
        return result;
    }
	
	/**
	 * 启动流程
	 * @param key 流程定义key
	 * @param variables 这个map 维护了了这个流程实例的变量  如:申请人
	 * @return  流程实例ID
	 */
	public static String createProcessInstanceByKey(String key,
			Map<String, Object> variables,RuntimeService runtimeService) {
		ProcessInstance pi=runtimeService // 运行时Service  
	            .startProcessInstanceByKey(key,variables);
		return pi.getId();
	}
	
	/**
	 * 启动流程
	 * @param applicant:申请人
	 * @return
	 */
	public static String createProcessInstance(Map<String,Object> map,RepositoryServiceImpl repositoryService,RuntimeService runtimeService){
		if(repositoryService == null){return null;}
		Map<String,Object> pd = getProcessDefinitionInfo(repositoryService);
		if(pd.isEmpty()){return null;}
		String pdId = MapUtils.getString(pd, "pdId");
		/*
		 * 获取流程定义候选人（userTask）表达式（参数名）列表
		 * [{activityId,activityName,candidates}]
		 */
		List<Map<String, Object>> activities = getCandidateUserIdExpressions(pdId,repositoryService);
		for (Map<String, Object> activity : activities){
			@SuppressWarnings("unchecked")
			List<String> candidates = (List<String>) activity.get("candidates");//如：jwc
			if (candidates.isEmpty()){continue;}
			for(String cand :candidates){// 3.获取对应角色的人员ids
				List<String> userIdList = queryUserListByRole(cand);
				/*if(userIdList.isEmpty()){
					break;
				}*/
				String userIds = "";
				for(int i=0;i<userIdList.size();i++){
					userIds+=userIdList.get(i);
					if(i<userIdList.size()-1){
						userIds+=",";
					}
				}
				map.put(cand, userIds);
			}
		}
		if(runtimeService == null){
			return null;
		}
		ProcessInstance pi = runtimeService.startProcessInstanceById(pdId, map);
		return pi.getId();
	}
	
	/**
	 * 获取审核人
	 * @param rightCode 用户权限代码
	 * @return
	 */
	public static List<String> queryUserListByRole(String rightCode){
		//activitiSettingService.queryUserListByRole(cand);
		List<String> userIdList = new ArrayList<String>();
		if("kjc".equals(rightCode)){//科技处
			userIdList.add("100001");
		} 
		if("zjz".equals(rightCode)){//专家组
			//userIdList.add("200002");
		}
		if("xmf".equals(rightCode)){//项目方
			userIdList.add("300003");
		}
		return userIdList;
	}
	
	/**
	 * 获取流程的环节信息
	 * @param processDefinitionId
	 * @return
	 */
	
	public static List<Map<String,Object>> getCandidateUserIdExpressions(String processDefinitionId,RepositoryServiceImpl repositoryService) {
		List<Map<String,Object>> ret = new ArrayList<Map<String,Object>>();
		if(repositoryService == null) return null;
		//获取流程定义的所有环节
    	ProcessDefinitionImpl processDefinitionImpl =  (ProcessDefinitionImpl)repositoryService.getDeployedProcessDefinition(processDefinitionId);
    	List<ActivityImpl>  activitiList = processDefinitionImpl.getActivities();
		for(ActivityImpl act : activitiList){ //流程节点信息
			Map<String,Object> prop = act.getProperties();//节点属性
			String type = prop.get("type").toString();//节点类型
			if("userTask".equals(type)){
				Map<String,Object> map = new HashMap<String, Object>();
				TaskDefinition td = (TaskDefinition) prop.get("taskDefinition");//任务定义类
				List<String> candidates = getLingCandidates(td);//候选人列表
				map.put("activityId", act.getId());//节点id
				map.put("activityName", prop.get("name"));//节点属性
				map.put("candidates", candidates);//候选人
				ret.add(map);
			}
		}
		return ret;
	}
	
	/**
	 * 获取候选人列表
	 * @param t
	 * @return
	 */
	public static List<String> getLingCandidates(TaskDefinition t){
		List<String> candidates = new ArrayList<String>();//候选人列表
		Set set = new HashSet<>();
		if(t.getCandidateUserIdExpressions().size() > 0){
			set = t.getCandidateUserIdExpressions();
		} else if(t.getCandidateGroupIdExpressions().size() > 0) {
			set = t.getCandidateGroupIdExpressions();
		}
		if(set.size() > 0){
			Object[] objs = set.toArray();
			for(Object obj : objs){
				if(obj != null){
					String tmp = obj.toString();//格式为${xxx}
					if(tmp.length() > 3){
						candidates.add(tmp.substring(2, tmp.length()-1));
					}
				}
			}
		} else if(t.getAssigneeExpression() != null){
			Object obj = t.getAssigneeExpression();
			if(obj != null){
				String tmp = obj.toString();//格式为${xxx}
				if(tmp.length() > 3){
					candidates.add(tmp.substring(2, tmp.length()-1));
				}
			}
		}
		return candidates;
	}
	
	/**
	 * 查询用户的待办任务
	 * @param userId
	 * @return  任务列表
	 */
	public static List<Task> queryTask(String userId,TaskService taskService) {
		if(taskService == null) return null;
		List<Task> tasks = taskService.createTaskQuery()
				.taskCandidateOrAssigned(userId)
				.orderByTaskCreateTime().asc()
				.list();	
		return tasks;	
	}
	
	/**
	 * 查询用户的待办任务
	 * @param userId 用户Id
	 * @param lcslId 流程实例Id
	 * @param taskService
	 * @return
	 */
	public static List<Task> queryTask(String userId,String lcslId,TaskService taskService) {
		if(taskService == null) return null;
		List<Task> tasks = taskService.createTaskQuery()
				 .processInstanceId(lcslId)
				 .taskCandidateOrAssigned(userId)
				 .orderByTaskCreateTime().asc()
				 .list();
		return tasks;	
	}
	

	/**
	 * 查询用户的待办任务数量
	 * @param userId
	 * @return  任务数量
	 */
	public static Long queryTaskCount(String userId,TaskService taskService) {
		if(taskService == null) return null;
		return taskService.createTaskQuery()
							.taskCandidateOrAssigned(userId)
							.count();	
	}
		
	/**
	 * 挂起一个流程实例
	 * @param lcslId 流程实例ID
	 */
	public static void saveSuspendProcessInstance(String lcslId,RuntimeService runtimeService) {
		runtimeService.suspendProcessInstanceById(lcslId);
	}

	/**
	 * 删除一个流程实例
	 * @param lcslId
	 * @param param
	 */
	public static void deleteProcessInstance(String lcslId, String param,RuntimeService runtimeService,HistoryService historyService) {
		/**
		 * 流程未结束
		 */
		runtimeService.deleteProcessInstance(lcslId,param);
		historyService.deleteHistoricProcessInstance(lcslId);
		
	}
	

	/**
	 * 认领任务
	 * @param taskId
	 * @param variables	
	 */
	public static void claimTask(String taskId, String userId,TaskService taskService) {
		//会检查该任务是否已经被认领，如果被认领则会抛出ActivitiTaskAlreadyClaimedException
		taskService.claim(taskId, userId);
	}

	/**
	 * 确认任务
	 * @param taskId
	 * @param userId
	 */
	public static void ownerTask(String taskId, String userId,TaskService taskService) {
		taskService.setOwner(taskId, userId);
		
	}

	/**
	 * 完成任务
	 * @param taskId
	 * @param variables	
	 */
	public static void completeTask(String taskId, Map<String, Object> variables,TaskService taskService) {
		taskService.complete(taskId, variables);
	}

	/**
	 * 批量完成任务
	 * @param tasks
	 * @param variables	
	 */
	public static void completeTask(List<Task> tasks, Map<String, Object> variables,TaskService taskService) {
		for(Task task : tasks){
			String taskId = task.getId();
			completeTask(taskId, variables,taskService);
		}
	}
	
	/**
	 * 获取我的历史任务
	 * @param processInstanceId
	 * @param processEngine
	 * @return
	 */
	public static List<Map<String,Object>> getHisActivitiList(String userId,ProcessEngine processEngine){  
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		
		String taskName = "";
		if("100001".equals(userId)){
			taskName="科技处";
		} else if("200002".equals(userId)||"400004".equals(userId)||"500005".equals(userId)){
			taskName="专家组";
		} else if("300003".equals(userId)){
			taskName="项目组";
		}
    	List<HistoricTaskInstance> list = processEngine.getHistoryService()  
	            .createHistoricTaskInstanceQuery().taskCandidateUser(userId).finished()
	            //.processInstanceId(processInstanceId) 
	            .orderByTaskCreateTime().asc()// 使用创建时间的升序排列  
	            .list();  
	    if(list!=null && list.size()>0){  
	        for(HistoricTaskInstance hti:list){  
	        	if(hti.getName().equals(taskName)){
	        		Map<String,Object> map = new HashMap<String, Object>();
		        	map.put("taskName", hti.getName());//环节名称
		        	map.put("claimTime", hti.getCreateTime());//审核时间
		        	map.put("taskId", hti.getId());
		        	map.put("lcslId", hti.getProcessInstanceId());
		        	/*String task = ActUtil.queryCurrentTask(hti.getProcessInstanceId(), processEngine.getTaskService());
		        	if(task == null){
		        		result.add(map);
		        	}*/
		        	result.add(map);
	        	}
	        }  
	    }
	    return result;
    } 
	
	/**
	 * 获取我的历史任务
	 * @param processInstanceId 流程实例Id
	 * @param taskService
	 * @param historyService
	 * @return
	 */
	public static String getHisActivitiList(String userId,String processInstanceId,TaskService taskService,HistoryService historyService) {
		List<Task> tasks = taskService.createTaskQuery()
				.processInstanceId(processInstanceId).list();
		String taskName = "";
		if (tasks != null && tasks.size() > 0) {
			List<HistoricTaskInstance> htis = historyService.createHistoricTaskInstanceQuery()
					.processInstanceId(processInstanceId).orderByTaskCreateTime().asc().list();
			for (int i = htis.size() - 1; i > 0; i--) {
				if (tasks.get(0).getName().equals(htis.get(i).getName())&& i != 1) {// 当前任务
					continue;
				} else {
					if ("".equals(taskName)) {
						taskName = htis.get(i).getName();
						if (userId.equals(htis.get(i).getAssignee())) {
							return htis.get(i).getId();
						}
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * 返回指定流程实例当前的用户任务(流程节点)名称。<br> 返回null，表示流程已结束
	 * @param processInstanceId
	 * @param taskService
	 * @return
	 */
	public static String queryCurrentTask(String processInstanceId,TaskService taskService){
		List<Task> curTasks = taskService.createTaskQuery().processInstanceId(processInstanceId).active().list();
		if (curTasks == null || curTasks.isEmpty()) {
			return null;
		}
		String result = "";
		for (Task task : curTasks) {
			result += task.getName() + ",";
		}
		result = result.substring(0, result.length() - 1);
		return result;
	}
	
}
